﻿using MBA.FluentExt.Ext;

using Newtonsoft.Json;

namespace MBA.FluentExt
{
	/// <summary>
	/// Appends an event handler to this object.
	/// </summary>
	public sealed class Listener : ExtObject
	{
		#region Fields

		internal readonly string eventName;

		#endregion Fields

		#region Constructors

		private Listener(string eventName)
		{
			this.eventName = eventName;
		}

		#endregion Constructors

		#region Methods

		/// <summary>
		/// Appends an event handler to this object..
		/// </summary>
		/// <param name="event">The event name to attach to.</param>
		/// <param name="handler">The handler javascript function to handle the event.</param>
		public static Listener On(Event @event, Raw handler)
		{
			var l = new Listener(@event.eventName);

			l.Config<Listener>("fn", handler);

			return l;
		}

		/// <summary>
		/// Causes the handler to be scheduled to run in an Ext.util.DelayedTask delayed by the specified number of milliseconds. If the event fires again within that time, the original handler is not invoked, but the new handler is scheduled in its place
		/// </summary>
		public Listener Buffer(uint buffer)
		{
			return Config<Listener>("buffer", buffer);
		}

		/// <summary>
		/// The number of milliseconds to delay the invocation of the handler after the event fires.
		/// </summary>
		public Listener Delay(uint delay)
		{
			return Config<Listener>("delay", delay);
		}

		/// <summary>
		/// The scope (this reference) in which the handler function is executed. If omitted, defaults to the object which fired the event.
		/// </summary>
		public Listener Scope(Raw scope)
		{
			return Config<Listener>("scope", scope);
		}

		/// <summary>
		/// True to add a handler to handle just the next firing of the event, and then remove itself.
		/// </summary>
		public Listener Single()
		{
			return Config<Listener>("single", true);
		}

		/// <summary>
		/// Only call the handler if the event was fired on the target Observable, not if the event was bubbled up from a child Observable.
		/// </summary>
		/// <param name="targetId">The target id, which will be passed to an Ext.getCmp() call.</param>
		public Listener Target(string targetId)
		{
			return Config<Listener>("target", Raw.Object("Ext.getCmp(\"{0}\")".FormatWith(targetId)));
		}

		/// <summary>
		/// Only call the handler if the event was fired on the target Observable, not if the event was bubbled up from a child Observable.
		/// </summary>
		/// <param name="target">The javascript fragment to get the target reference.</param>
		public Listener Target(Raw target)
		{
			return Config<Listener>("target", target);
		}

		#endregion Methods

		protected override string ExtNamespace
		{
			get { return null; }
		}

	}
}